home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / asm_n_z.zip / TK.ASM < prev    next >
Assembly Source File  |  1987-05-05  |  21KB  |  614 lines

  1. page    55,132
  2. title    TK - Token Parsing filter
  3. ;
  4. ;    TK --- A Simple Token Parsing Filter for DOS 2.0
  5. ;
  6. ;    (c) Copyright 1984 by    Jim Mott
  7. ;                3710 Slopeview Drive
  8. ;                Sunnyvale, CA 95148
  9. ;                (408) 274-2620
  10. ;    All rights reserved. Permission granted to use this software for
  11. ;    personal, noncommercial purposes only.
  12. ;
  13. ;
  14. ;    This program is designed to be a filter for DOS 2.0.
  15. ;    It will tokenize its input and allow subsetting and/or
  16. ;    single token per line output.
  17. ;
  18. ;    The format of the command is:
  19. ;
  20. ;    TK {/RJx | /LJx} {/0} {{/v} | {/v/v}}
  21. ;      where /RJx means right justify all tokens to x positions
  22. ;        /LJx means left justify all tokens to x positions
  23. ;             In the two entries x must be in [1..15]
  24. ;        /0   means output one token per line
  25. ;        /v   means select token v for output. You may select any
  26. ;             number, up to 255, of tokens to output. Repeats are
  27. ;             allowed and you may change the order of the input tokens
  28. ;             on the output line.
  29. ;
  30. ;    For example, to extract the list of users from a VM directory file and
  31. ;    write a sorted list of them without passwords to the printer the
  32. ;    following command line would be used.
  33. ;
  34. ;    FIND "USER " < DIRECT.VM | TK/LJ8/2/4/5/6/7/8/9 | SORT > PRN
  35. ;
  36. ;
  37. ;    For example, to find a list of all sub-directories of the current
  38. ;    directory sorted by sub-directory name we would use the following
  39. ;    command line:
  40. ;
  41. ;    DIR | FIND "<DIR>" | TK/LJ8/1/3/4 | SORT | MORE
  42. ;
  43. ;
  44. ;    For example, to generate a sorted list of all words used in a document
  45. ;    with one word per line we could use the following command line:
  46. ;
  47. ;    TK/RJ8/0 < FOOBAR.DOC | SORT | MORE
  48. ;
  49. ;
  50. ;
  51. ;
  52. ;
  53. ;
  54. ;
  55. ;
  56. ;
  57. ;
  58. ;
  59. ;
  60. stack    segment para    stack    'STACK'
  61.     db    8 dup('Jim Mott  (408) 274-2620')
  62. stack    ends
  63. ;
  64. ;
  65. dsect    segment para    'DATA'
  66. buffer    db    255 dup('?')        ; where to put the data
  67.     db    ' '            ; be sure to end scan correctly
  68. ;
  69. glen    dw    0            ; length of gbuff
  70. gbptr    dw    gbuff            ; point to start of buffer
  71. gbuff    db    255 dup('G')        ; buffer used by bufget
  72. ;
  73. flag1    db    ?            ; options enabled
  74. f1rj    equ    01h            ; right justify tokens
  75. f1lj    equ    02h            ; left justify tokens
  76. f1one    equ    04h            ; output one token per line
  77. f1sub    equ    08h            ; substring function requested
  78. f1work    equ    10h            ; fill trailing spaces
  79. f1oerr    equ    20h            ; error in options string
  80. f1eof    equ    40h            ; end of file on standard input device
  81. f1qeof    equ    80h            ; queue the end of file
  82. ;
  83. spaces    db    ?            ; number of trailing spaces required
  84. ;
  85. toksiz    db    ?            ; token size if (f1rj or f1lj)
  86. ;
  87. three    db    3            ; length of each entry
  88. tokcnt    db    ?            ; count of tokens in table
  89. toktbl    db    3*255 dup('0')        ; table of token pointers and lengths
  90. ;
  91. outcnt    db    ?            ; number of subsetting entries in
  92.                     ; outers
  93. outers    db    255 dup('1')        ; list of token numbers to output
  94. ;
  95. tokptr    dw    ?            ; pointer to free token space
  96. tokens    db    900 dup('2')        ; string space of tokens
  97. ;
  98. msgver    db    'TK: Incorrect DOS version. Must be at least 2.00.'
  99.     db    0dh,0ah,'$'
  100. optmsg    db    'TK: Incorrect parameters given.'
  101.     db    0dh,0ah
  102. optmgl    equ    $ - optmsg
  103. noroom    db    'TK: No room for user on device.'
  104.     db    0dh,0ah
  105. lnoroom    equ    $ - noroom
  106. chrspa    db    ' '            ; a space to output
  107. chrclf    db    0dh,0ah            ; <cr><lf> sequence
  108. dsect    ends
  109. ;
  110. ;
  111. csect    segment para    'CODE'
  112.     assume cs:csect,ds:dsect,ss:stack
  113. ;
  114. main    proc    far
  115. ;
  116.     push    ds            ; set up a return address
  117.     sub    ax,ax            ; we want to return to DS:0000
  118.     push    ax
  119.     mov    ax,dsect        ; point to start of data area
  120.     mov    ds,ax            ; make assume and reality agree
  121.     mov    ah,30h            ; get DOS version number
  122.     int    21h            ; call OS to get it
  123.     cmp    al,2            ; is it at least 2.00?
  124.     jnl    main00            ; yesy - good enough
  125.     lea    dx,msgver        ; no - point to the "Bad DOS version"
  126.     mov    ah,9            ; message and use DOS 1.?? function
  127.     int    21h            ; call to print it.
  128.     ret                ; and do a long return
  129. ;
  130. main00:    call    options            ; parse the options (at ES:80) and set
  131.                     ; flags
  132.     mov    ax,ds            ; make ES and DS the same now
  133.     mov    es,ax            ; so the string moves work nicely.
  134.     test    flag1,f1oerr        ; was there and error in the options
  135.     jz    main01            ; no - then go with this baby
  136.     lea    dx,optmsg        ; yes - point to options error message
  137.     mov    cx,optmgl        ; get length of message
  138.     mov    bx,2            ; error output device handle
  139.     mov    ah,40h            ; set DOS function number for
  140.     int    21h            ; "write to file or device" & call DOS
  141.     jmp    short    main03        ; and return as done
  142. ;
  143. main01:    mov    tokcnt,0        ; no tokens in the table
  144.     lea    ax,tokens        ; point to start of token work area
  145.     mov    tokptr,ax        ; save pointer to next free byte
  146.     call    bufget            ; read in a buffer
  147.     test    flag1,f1eof        ; is there any data in the read buffer
  148.     jnz    main03            ; no - we are done with this pgm then
  149.     dec    cx            ; yes - ignore the trailing <cr>
  150.     jle    main01            ; if length is =<0 just get next line
  151.     lea    bx,buffer        ; point to the first byte of the data
  152. ;
  153. main02:    call    nextok            ; get the next token
  154.     or    cx,cx            ; are we done with this line yet
  155.     jnz    main02            ; no - get yet another token
  156.     call    write            ; write the lines
  157.     jmp    short    main01        ; and loop for the next line
  158. ;
  159. main03:    call    crlf            ; write a final <cr><lf> sequence
  160.     mov    al,0            ; put 0 in al - return code to post
  161.     mov    ah,4ch            ; terminate a process code
  162.     int    21h            ; end this program
  163. ;
  164. main    endp
  165. ;
  166. ;
  167. ;    OPTIONS - This subroutine will parse the options passed to the
  168. ;          program and set the required bits in flag1. No registers
  169. ;          are preserved since we are called only once, before the
  170. ;          program has really started.
  171. ;
  172. options    proc    near
  173. ;
  174.     mov    outcnt,0        ; initialize outers count
  175.     mov    si,81h            ; point to the first parms character
  176. ;
  177. opt01:    mov    al,byte ptr es:0[si]    ; get a byte from the parm string
  178.     inc    si            ; point to the next byte
  179.     cmp    al,0dh            ; is it the end of the string?
  180.     jne    opt02            ; no - goody, more data to process
  181.     ret                ; yes, return to the caller then
  182. ;
  183. opt02:    cmp    al,' '            ; allow spaces anywhere before slashes
  184.     je    opt01            ; ignore them though
  185.     cmp    al,'/'            ; we have to start with a slash now
  186.     je    opt04            ; if it is a slash then process it
  187. ;
  188. opterr:    or    flag1,f1oerr        ; otherwise set the options error flag
  189.     ret                ; and return
  190. ;
  191. opt04:    mov    al,byte ptr es:0[si]    ; get the next character after slash
  192.     inc    si            ; point to next character in parms
  193.     cmp    al,'a'            ; is it lower case or funny?
  194.     jl    opt4a            ; no - process it normally then
  195.     sub    al,'a'-'A'        ; yes - map lower case to upper
  196. ;
  197. opt4a:    cmp    al,'L'            ; might it be left justify or numeric
  198.     jl    optnum            ; perhaps numeric - check it out
  199.     jne    opt05            ; it is not LJ for sure
  200.     or    flag1,f1lj        ; assume it is LJ for the moment
  201.     test    flag1,f1rj        ; make sure this isn't a duplicate
  202.     jnz    opterr            ; if RJ already then big problems
  203.     jmp    short    opt06        ; and rejoin common justify code
  204. ;
  205. opt05:    cmp    al,'R'            ; might it be right justify (RJ)?
  206.     jne    opterr            ; no - then it is an error
  207.     or    flag1,f1rj        ; yes - assume for the moment it is
  208.     test    flag1,f1lj        ; make sure we aren't trying to left
  209.     jnz    opterr            ; justify too - if we are we are in
  210.                     ; deep s..t
  211. opt06:    mov    al,byte ptr es:0[si]    ; get the next character
  212.     inc    si            ; point to the next character in parms
  213.     cmp    al,'J'            ; is it the J we expect?
  214.     je    opt6a            ; yes - process it normally then
  215.     cmp    al,'j'            ; is it a lower case J
  216.     jne    opterr            ; no - that's too bad.
  217. ;
  218. opt6a:    mov    al,byte ptr es:0[si]    ; get the first byte of the number
  219.     inc    si            ; point to next character in parms
  220.     call    decbin            ; is it a number?
  221.     jc    opterr            ; no - then we have an error
  222.     or    al,al            ; is the field size 0?
  223.     je    opterr            ; yes - it is in error then
  224.     cmp    al,15            ; is field size more than 15?
  225.     jg    opterr            ; yes - it is in error then
  226.     mov    toksiz,al        ; save the justified field size
  227.     jmp    short opt01        ; and process further options
  228. ;
  229. optnum:    call    decbin            ; is it a number after slash?
  230.     jc    opterr            ; no - then it is an error
  231.     or    al,al            ; zero is special
  232.     jne    opt08            ; not zero - save it in array then
  233.      or    flag1,f1one        ; zero means one token per line
  234.     jmp    short    opt01        ; process some other token then
  235. ;
  236. opt08:    sub    cx,cx            ; get a zeroed double register
  237.     mov    cl,outcnt        ; get offset into outers for this guy
  238.     lea    bx,outers        ; point just before list of outers
  239.     add    bx,cx            ; bx points to origin 1 save spot
  240.